﻿using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using ruleEngineDemo.engine.factory.product;
using ruleEngineDemo.engine.viewmodel;
using ruleEngineDemo.Engine.Extensions;
using RulesEngine.Models;

namespace ruleEngineDemo.engine.rulesengine.product
{
    public class EfRules : IEfRules
    {
        private dynamic[] _inputs = new dynamic[] { };

        /// <summary>
        /// 执行rules
        /// </summary>
        /// <returns></returns>
        public RulesResult? Run()
        {
            if (! _inputs.Any())
            {
                return null;
            }

            var files = Directory.GetFiles(Directory.GetCurrentDirectory(), "Discount.json", SearchOption.AllDirectories);
            if (files == null || files.Length == 0)
                throw new Exception("Rules not found.");

            var fileData = File.ReadAllText(files[0]);
            var workflow = JsonConvert.DeserializeObject<List<Workflow>>(fileData);

            RulesEngineDemoContext db = new RulesEngineDemoContext();
            if (db.Database.EnsureCreated())        //创建数据
            {
                db.Workflows.AddRange(workflow);
                db.SaveChanges();
            }

            var wfr = db.Workflows.Include(i => i.Rules).ThenInclude(i => i.Rules).ToArray();

            var bre = new RulesEngine.RulesEngine(wfr, null);

            List<RuleResultTree> resultList = bre.ExecuteAllRulesAsync("Discount", _inputs).Result;

            RulesResult rRt = new RulesResult
            {
                IsPass = true,
                Errors = new List<string>()
            };
            foreach (var item in resultList)
            {
                if (item.IsSuccess == false)
                {
                    rRt.IsPass = false;
                    rRt.Errors.Add($"Failed: {item.Rule.RuleName}");
                }
            }
            return rRt;
        }

        /// <summary>
        /// 设置条件
        /// </summary>
        /// <param name="conditions"></param>
        public void SetConditions(dynamic[] conditions)
        {
             _inputs = conditions;
        }
    }
}
